#include "stdafx.h" 
#include "dll_manager.h"
#include <utility/ini_op.h>
#include <utility/api_tools.h>
#include <interface/log_interface.h>
#include "main_object.h"


#pragma warning(disable:4996)

dll_manager::dll_manager(void)
{
	this->login_ = NULL;
	this->main_obj_ = new main_object;

	this->main_obj_->read_app_data_path();
	aot::tt::utility::dir_create(this->main_obj_->get_temp_data_path());
}

void
dll_manager::final_destroy_plugins()
{
	std::for_each(this->plugins_.rbegin(), this->plugins_.rend(), __release_obj());
}

void
dll_manager::final_destroy_login_plugin()
{
	if( this->login_ )
	{
		this->login_->final_destroy();
	}
}

void
dll_manager::final_destroy_component()
{
	std::for_each(this->component_.rbegin(), this->component_.rend(), __release_obj());
}

void
dll_manager::final_destroy_core()
{
	std::for_each(this->core_.rbegin(), this->core_.rend(), __release_obj());
}

dll_manager::~dll_manager(void)
{
	destroy_plugins();

	destroy_login_plugin();

	destroy_component();
	destroy_core();
	
	if( this->main_obj_ )
	{
		aot::tt::utility::dir_delete(this->main_obj_->temp_data_path_);
		delete this->main_obj_;
		this->main_obj_ = NULL;
	}	
}

bool dll_manager::fill_dll_regist_param(aot::tt::idll::dll_regist_param_t* p)
{
	p->mi = this->main_obj_;
	p->shr_alloc = (aot::tt::ialloc *)this->main_obj_->shr_alloc_;

	return true;
}

bool 
dll_manager::get_modules_info(dll_manager::modules_cfg_list_type* cfg_list, const char* domain)
{
// 	aot::tt::iobj_auto_ptr<aot::tt::ixml_parser> xml_parser_ptr;
// 
// 	dll_module* p = NULL;
// 	aot::tt::xml_string_impl xml_str;
// 	int i = 0;
// 
// 	tstring		path = "//modules/";
// 	path += domain;
// 	path += "/elem";
// 
// 	tstring modules_path = this->main_obj_->get_app_data_path();
// 	modules_path += "modules.xml";
// 	
// 	p = find_core("idll.xml_parser.dll");
// 
// 	if( !p )
// 	{
// 		aot_log_error(AOT_LM_EMERG, "%s", "can't find xml_parser.dll !");
// 		return false;
// 	}
// 
// 	if( !p->obj()->query_interface(xml_parser_ptr, "ixml_parser"))
// 	{
// 		aot_log_error(AOT_LM_EMERG, "%s", "can't query [ixml_parser] interface !");
// 		return false;
// 	}
// 
// 	if( !xml_parser_ptr->open(modules_path.c_str()) )
// 	{
// 		aot_log_error(AOT_LM_EMERG, "%s", "open [%s] failed!", modules_path.c_str());
// 		return false;
// 	}
// 
// 	if( xml_parser_ptr->nodes_select(path.c_str()) > 0)
// 	{
// 		modules_cfg_t cfg;
// 
// 		while( xml_parser_ptr->nodes_goto_next() )
// 		{
// 			xml_parser_ptr->get_cur_element()->get_attr(xml_str, "enable", "0");
// 
// 			if( 0 != strcmp(xml_str.c_str(), "1") )
// 			{
// 				xml_parser_ptr->get_cur_element()->get_attr(xml_str, "name", "");
// 				aot_log_debug(AOT_LM_NOTICE, "[%s] had disable !", xml_str.c_str());
// 				continue;
// 			}
// 
// 			xml_parser_ptr->get_cur_element()->get_attr(xml_str, "can_mgr", "0");
// 			cfg.can_mgr = atoi(xml_str.c_str());
// 
// 			xml_parser_ptr->get_cur_element()->get_attr(xml_str, "name", "");
// 			if( xml_str.length() > 0 )
// 			{
// 				cfg.name = xml_str.c_str();
// 				cfg_list->push_back(cfg);
// 			}
// 		}
// 
// 		return true;
// 	}

	return false;
}

bool 
dll_manager::init_and_regist_core()
{
	dll_module* p = new dll_module();

	aot::tt::idll::dll_regist_param_t param;

	fill_dll_regist_param(&param);
	param.token = p;

	if( !p->init("log.dll") || !p->obj()->on_regist(&param, NULL) ) {
		delete p;
	}
	else {

		this->core_.push_back(p);

		aot::tt::ilog *log_obj = NULL;

		if( p->obj()->query_interface((void**)&log_obj, "ilog") ) {

			//tstring log_cfg_fn = aot::tt::utility::get_app_path();
			//tstring app_root_path;


			//const char* pos = 
			//	aot::tt::utility::str_find_lastof(log_cfg_fn.c_str(), "\\/", (int)log_cfg_fn.size()-1);

			//if( pos )
			//	app_root_path = log_cfg_fn.substr(0, pos - log_cfg_fn.c_str() + 1);
			//else
			//	app_root_path = log_cfg_fn;

			//log_cfg_fn = app_root_path + "config\\log.ini";
			tstring log_cfg_fn = this->main_obj_->get_app_data_path();
			log_cfg_fn += "log.ini";

			aot_log_init(log_obj);
			aot::tt::log_helper::instance()->global_config_from_file("global", log_cfg_fn.c_str());
			aot_log_cfg_from_file("imain", NULL);

			aot_log_debug(AOT_LM_DEBUG, "%s", "main log init ok !");
		}
	}


	p = new dll_module();

	if( !p->init("xml_parser.dll")  || !p->obj()->on_regist(&param, NULL) ) {

		aot_log_error(AOT_LM_EMERG, "%s", "xml_parser.dll load failed !");
		delete p;
		return false;
	}

	this->core_.push_back(p);
	init_res_string();
	
	return true;
}

bool 
dll_manager::init_and_regist_login_plugins(aot::tt::idll::dll_regist_param_t* param)
{
	modules_cfg_list_type lst;
	if( !get_modules_info(&lst, "login" ) ) {

		aot_log_error(AOT_LM_EMERG, "%s", "init_and_regist_login_plugins failed !");
		return false;
	}

	if( lst.size() != 1 ) {

		aot_log_error(AOT_LM_EMERG, "%s", "init_and_regist_login_plugins failed !");
		return false;
	}

	modules_cfg_list_type::iterator iter = lst.begin();
	tstring dll_path = "";

	this->login_ = new dll_module;
	dll_path = this->main_obj_->get_app_root_path();
	dll_path += iter->name;
	param->token = this->login_;

	aot::tt::result_t rg_ret;
	memset(&rg_ret, 0, sizeof(aot::tt::result_t));

	if( !this->login_->init(dll_path.c_str() ) ||
		!this->login_->obj()->on_regist(param, &rg_ret)) {

		aot_log_error(AOT_LM_ALERT, "loading %s failed !", iter->name.c_str());
		//remove_trans_msg(this->login_);
		delete this->login_;
		this->login_ = NULL;
		return false;
	}

	aot_log_debug(AOT_LM_DEBUG, "loading %s ok !", iter->name.c_str());
	
	return true;
}

bool 
dll_manager::init_plugins()
{
	modules_cfg_list_type lst;
	if( !get_modules_info(&lst, "plugins") ) {

		aot_log_error(AOT_LM_EMERG, "%s", "get_modules_info failed !");
		return false;
	}

	modules_cfg_list_type::iterator iter = lst.begin();
	tstring dll_path = "";

	for( ; iter != lst.end(); ++iter )
	{
		dll_module* p = new dll_module();
		p->can_mgr_ = iter->can_mgr;
		dll_path = this->main_obj_->get_app_root_path();
		dll_path += iter->name;
		if( !p->init(dll_path.c_str()) ) {

			aot_log_error(AOT_LM_ALERT, "loading %s failed !", iter->name.c_str());
			delete p;
			continue;
		}

		aot_log_debug(AOT_LM_DEBUG, "loading %s ok !", iter->name.c_str());

		this->plugins_.push_back(p);
	}
	
	return true;
}

bool 
dll_manager::init_component()
{
	modules_cfg_list_type lst;
	if( !get_modules_info(&lst, "component") ) {

		aot_log_error(AOT_LM_EMERG, "%s", "get_modules_info failed !");
		return false;
	}
	tstring dll_path = "";
	modules_cfg_list_type::iterator iter = lst.begin();
	for( ; iter != lst.end(); ++iter )
	{
		dll_module* p = new dll_module();
		dll_path = this->main_obj_->get_app_root_path();
		dll_path += iter->name;
		if( !p->init(dll_path.c_str()) ) {
			aot_log_error(AOT_LM_ALERT, "loading %s failed !", iter->name.c_str());
			delete p;
			continue;
		}
		aot_log_debug(AOT_LM_DEBUG, "loading %s ok !", iter->name.c_str());
		this->component_.push_back(p);
	}
	
	return true;
}

void 
dll_manager::destroy_plugins()
{
	std::for_each(this->plugins_.rbegin(), this->plugins_.rend(), __release_dll());

	this->plugins_.clear();
}

void 
dll_manager::destroy_component()
{
	std::for_each(this->component_.rbegin(), this->component_.rend(), __release_dll());

	this->component_.clear();
}

void 
dll_manager::destroy_core()
{
	aot_log_destroy();

	std::for_each(this->core_.rbegin(), this->core_.rend(), __release_dll());

	this->core_.clear();
}

bool 
dll_manager::regist_plugins(aot::tt::idll::dll_regist_param_t* param)
{
	aot::tt::result_t rg_ret;

	dll_plugins_iter iter = plugins_.begin();

	for( ; iter != plugins_.end(); ++iter ) {

		dll_module* dll = *iter;
		param->token = dll;

		memset(&rg_ret, 0, sizeof(rg_ret));

		if( dll->obj()->on_regist(param, &rg_ret ) ) {
			////dll->key_ = rg_ret.ret;
		}
		else
		{
			remove_trans_msg(dll);
		}
	}
 
	return true;
}

bool 
dll_manager::regist_component(aot::tt::idll::dll_regist_param_t* param)
{
	aot::tt::result_t rg_ret;

	dll_component_iter iter = component_.begin();

	for( ; iter != component_.end(); ++iter ) {

		dll_module* dll = *iter;
		param->token = dll;

		memset(&rg_ret, 0, sizeof(rg_ret));

		if( dll->obj()->on_regist(param, &rg_ret ) ) {

			dll->key_ = rg_ret.ret;
		}
	}
// 	main_obj_->glb_data_->init(main_obj_);
// 	main_obj_->read_ui_config();
	//main_obj_->interface_.init_component_query(main_obj_, this);
	return true;
}

dll_module*	
dll_manager::find_plugins(unsigned int key)
{
	dll_plugins_iter iter = plugins_.begin();

	for( ; iter != plugins_.end(); ++iter ) {

		dll_module* dll = *iter;

		if( NULL == dll->obj() )
			continue;

		if( dll->key_ == key )
			return dll;
	}

	return NULL;
}

dll_module*	
dll_manager::find_plugins(const char* key)
{
	dll_plugins_iter iter = plugins_.begin();

	for( ; iter != plugins_.end(); ++iter ) {

		dll_module* dll = *iter;

		if( NULL == dll->obj() )
			continue;
		tstring str = dll->obj()->interface_name() ;
		if( 0 == strcmp(dll->obj()->interface_name(), key) )
			return dll;
	}

	if( this->login_ && 0 == strcmp(this->login_->obj()->interface_name(), key) )
		return this->login_;

	return NULL;
}

dll_module*	
dll_manager::find_component(const char* key)
{
	dll_component_iter iter = component_.begin();

	for( ; iter != component_.end(); ++iter ) {

		dll_module* dll = *iter;

		if( NULL == dll->obj() )
			continue;

		if( 0 == strcmp(dll->obj()->interface_name(), key) )
			return dll;
	}

	return find_core(key);
}

dll_module*	
dll_manager::find_core(const char* key)
{
	dll_core_iter iter = core_.begin();

	for( ; iter != core_.end(); ++iter ) {

		dll_module* dll = *iter;

		if( NULL == dll->obj() )
			continue;

		if( 0 == strcmp(dll->obj()->interface_name(), key) )
			return dll;
	}

	return NULL;
}

dll_module*	
dll_manager::find_all(const char* key)
{
	dll_module* dll = NULL;

	if( NULL == (dll = find_plugins(key)) ) {

		dll = find_component(key);
	}

	return dll;
}


// BOOL dll_manager::init_res_string()
// {
// 	aot::tt::res_parser_string_helper res_str_parser;
// 	if ( !this->main_obj_->query_interface(res_str_parser, "ires_parser") )
// 	{
// 		return FALSE;
// 	}
// 	tstring xml_fn =this->main_obj_->get_app_root_path();
// 	xml_fn += "language\\2052\\res_tatamain_string.xml";
// 	if ( !res_str_parser.open(xml_fn.c_str()) )
// 	{
// 		return FALSE;
// 	}
// 	
// 	insert_res_string("APP_NAME", APP_NAME, &res_str_parser);
// 	insert_res_string("IDD_UI_MANAGER_UIM", IDD_UI_MANAGER_UIM, &res_str_parser);
// 	insert_res_string("IDC_BTN_OK_COMMON", IDC_BTN_OK_COMMON, &res_str_parser);
// 	insert_res_string("IDC_BTN_CANCEL_COMMON", IDC_BTN_CANCEL_COMMON, &res_str_parser);
// 	insert_res_string("IDC_BTN_APPLY_COMMON", IDC_BTN_APPLY_COMMON, &res_str_parser);
// 	insert_res_string("IDC_BTN_BROWSE_COMMON", IDC_BTN_BROWSE_COMMON, &res_str_parser);
// 	insert_res_string("IDC_BTN_ADD_COMMON", IDC_BTN_ADD_COMMON, &res_str_parser);
// 	insert_res_string("IDC_BTN_MODIFY_COMMON", IDC_BTN_MODIFY_COMMON, &res_str_parser);
// 	insert_res_string("IDC_BTN_DEL_COMMON", IDC_BTN_DEL_COMMON, &res_str_parser);
// 	insert_res_string("TAB_LEFT_UIM", TAB_LEFT_UIM, &res_str_parser);
// 	insert_res_string("TAB_TOP_UIM", TAB_TOP_UIM, &res_str_parser);
// 	insert_res_string("TAB_BOTTOM_UIM", TAB_BOTTOM_UIM, &res_str_parser);
// 	insert_res_string("LIST_DISPLAY_UIM", LIST_DISPLAY_UIM, &res_str_parser);
// 	insert_res_string("LIST_PANEL_UIM", LIST_PANEL_UIM, &res_str_parser);
// 	insert_res_string("BTN_UP_UIM", BTN_UP_UIM, &res_str_parser);
// 	insert_res_string("BTN_DOWN_UIM", BTN_DOWN_UIM, &res_str_parser);
// 	insert_res_string("IDC_STATIC_LEFT_PANEL_LIST_UIM", IDC_STATIC_LEFT_PANEL_LIST_UIM, &res_str_parser);
// 	
// 	insert_res_string("TITLE_ASW", TITLE_ASW, &res_str_parser);
// 	insert_res_string("TAB0_ASW", TAB0_ASW, &res_str_parser);
// 	insert_res_string("TAB1_ASW", TAB1_ASW, &res_str_parser);
// 	insert_res_string("TITLE_CUE_ASW", TITLE_CUE_ASW, &res_str_parser);
// 	insert_res_string("PATH_SHORT", PATH_SHORT, &res_str_parser);
// 	insert_res_string("URL_WEBPAGE_ASW", URL_WEBPAGE_ASW, &res_str_parser);
// 	insert_res_string("ICON_SHORT", ICON_SHORT, &res_str_parser);
// 	insert_res_string("IDC_STATIC_ICON_SHORTCUT_ASW", IDC_STATIC_ICON_SHORTCUT_ASW, &res_str_parser);
// 	insert_res_string("IDC_STATIC_MODE_ASW", IDC_STATIC_MODE_ASW, &res_str_parser);
// 	insert_res_string("IDC_STATIC_CUSTOMIZE_ICON_CUE_ASW", IDC_STATIC_CUSTOMIZE_ICON_CUE_ASW, &res_str_parser);
// 	insert_res_string("IDC_STATIC_BROWSE_ASW", IDC_STATIC_BROWSE_ASW, &res_str_parser);
// 
// 	insert_res_string("OPEN_WEBPAGE_BY_IE", OPEN_WEBPAGE_BY_IE, &res_str_parser);
// 	insert_res_string("OPEN_WEBPAGE_BY_MAIN", OPEN_WEBPAGE_BY_MAIN, &res_str_parser);
// 	insert_res_string("TITLE_MS", TITLE_MS, &res_str_parser);
// 	insert_res_string("TITLE_MW", TITLE_MW, &res_str_parser);
// 
// 	insert_res_string("IDC_LOCK_STATUS_LOCK", IDC_LOCK_STATUS_LOCK, &res_str_parser);
// 	insert_res_string("IDC_CTRL_CUE_LOCK", IDC_CTRL_CUE_LOCK, &res_str_parser);
// 	insert_res_string("IDC_BTN_LOCK_LOCK", IDC_BTN_LOCK_LOCK, &res_str_parser);
// 	insert_res_string("IDC_STATIC_LOCK_PWD_LOCK", IDC_STATIC_LOCK_PWD_LOCK, &res_str_parser);
// 	insert_res_string("IDC_STATIC_PWD_CUE_LOCK", IDC_STATIC_PWD_CUE_LOCK, &res_str_parser);
// 	insert_res_string("IDC_LOCK_SUGGEST_LOCK", IDC_LOCK_SUGGEST_LOCK, &res_str_parser);
// 	insert_res_string("IDC_LOCK_QUESTION_LOCK", IDC_LOCK_QUESTION_LOCK, &res_str_parser);
// 
// 	insert_res_string("SOUND_OPEN_TRAY", SOUND_OPEN_TRAY, &res_str_parser);
// 	insert_res_string("SOUND_CLOSE_TRAY", SOUND_CLOSE_TRAY, &res_str_parser);
// 	insert_res_string("MSG_OPEN_MODE_TRAY", MSG_OPEN_MODE_TRAY, &res_str_parser);
// 	insert_res_string("MSG_OPEN_MODE_OPEN", MSG_OPEN_MODE_OPEN, &res_str_parser);
// 	insert_res_string("TOOPTIP_FORMAT_TRAY", TOOPTIP_FORMAT_TRAY, &res_str_parser);
// 	insert_res_string("IDD_TRAY_MSG_SHOW_TMS", IDD_TRAY_MSG_SHOW_TMS, &res_str_parser);
// 	insert_res_string("IDC_STATIC_CANCEL_SHARK_TMS", IDC_STATIC_CANCEL_SHARK_TMS, &res_str_parser);
// 	insert_res_string("IDC_STATIC_READ_ALL_MSG_TMS", IDC_STATIC_READ_ALL_MSG_TMS, &res_str_parser);
// 
// 	insert_res_string("IDC_BTN_FEED_BACK_TOOLTIP", IDC_BTN_FEED_BACK_TOOLTIP, &res_str_parser);
// 	insert_res_string("IDS_CLICK_OUT_MSG", IDS_CLICK_OUT_MSG, &res_str_parser);
// 	insert_res_string("MSGBOX_LOGOUT", MSGBOX_LOGOUT, &res_str_parser);
// 	insert_res_string("MSGBOX_LOGOUT_TITLE", MSGBOX_LOGOUT_TITLE, &res_str_parser);
// 	insert_res_string("MSGBOX_DEL_SHORTCUT", MSGBOX_DEL_SHORTCUT, &res_str_parser);
// 	insert_res_string("MSGBOX_IM_DISCNNT", MSGBOX_IM_DISCNNT, &res_str_parser);
// 	return TRUE;
// }



BOOL dll_manager::save_modules_info()
{
	aot::tt::iobj_auto_ptr<aot::tt::ixml_parser> xml_parser_ptr;
	aot::tt::xml_string_impl xml_str;
	aot::tt::iobj_auto_ptr<aot::tt::idll> dll;
	if( dll_manager::instance()->get_main_obj()->query_interface(dll, "idll.xml_parser.dll") )
	{
		if( dll.get() )
		{
			if( !dll->query_interface(xml_parser_ptr, "ixml_parser") )
			{
				aot_log_error(AOT_LM_EMERG, "%s", "can't query [ixml_parser] interface !");
				return FALSE;
			}
		}
		else
		{
			return FALSE;
		}
	}
	tstring xml_path = "";
	if( xml_parser_ptr->create("modules") )
	{
		xml_parser_ptr->goto_root();
		xml_parser_ptr->get_cur_element()->create_child("component", "");
		xml_path = "//modules/component";
		if( xml_parser_ptr->nodes_select(xml_path.c_str()) > 0)
		{
			dll_component_iter iter = this->component_.begin();
			for( ; iter != this->component_.end(); iter++ )
			{
// 				xml_parser_ptr->get_cur_element()->create_child("elem", "");
// 				xml_parser_ptr->get_cur_element()->set_child_attr("elem", "enable", (*iter)->);
// 				xml_parser_ptr->get_cur_element()->set_child_attr("elem", "");
// 				xml_parser_ptr->get_cur_element()->set_child_attr("elem", "");
			}
			//component_
			
		}
	}

	return TRUE;
}

void
dll_manager::remove_trans_msg(dll_module* dllm)
{
	std::vector<dll_module*>::iterator iter = main_obj_->trans_msg_.begin();
	for( ; iter != main_obj_->trans_msg_.end(); iter++ )
	{
		if( (*iter) == dllm)
		{
			main_obj_->trans_msg_.erase(iter);
			return;
		}
	}
}